﻿using Nemerle;
using Nemerle.Collections;
using Nemerle.Text;
using Nemerle.Utility;

using System;
using System.Collections.Generic;
using System.Linq;
using Nemerle2.Compiler;
using Nemerle.Peg;
using MsCci = Microsoft.Cci;
using Nemerle.Assertions;

namespace MetadataReader.CCI
{
  /// <summary>
  /// Description of CciParameterInfo.
  /// </summary>
  internal class CciParameterInfo : IParameterInfo
  {
    public Modifiers         : ParameterModifiers
    {
      [Nemerle.Memoize]
      get
      {
        def hasThisModifier() : bool
        {
          _paramDef.Index == 0 // skip check for other parameters
          &&
            match (_paramDef.ContainingSignature)
            {
              | method is MsCci.IMethodDefinition => method.IsExtension()
              | _ => false
            }
        }

        if(_paramDef.IsOut)
          ParameterModifiers.Out
        else if(_paramDef.IsByReference)
          ParameterModifiers.Ref
        else if(hasThisModifier())
          ParameterModifiers.This
        else
          ParameterModifiers.None
      }
    }

    public UniqueKey : long { get { throw NotImplementedException() } }

    public CustomAttributes  : ICustomAttributes
    {
      [Memoize] get { CciCustomAttributes(_provider, _paramDef.Attributes) }
    }

    public Type              : FixedType
    {
      [Memoize]
      get
      {
        def ty = _provider.GetType(_paramDef.Type);

        if (_paramDef.IsByReference) FixedType.Ref(ty)
        else if (_paramDef.IsOut) FixedType.Out(ty)
        else ty;
      }
    }

    public Location          : Location           { get; set; }

    public Name              : string   { get { _paramDef.Name.Value } }
    public NameLocation      : Location { get; set; }

    private _paramDef : MsCci.IParameterDefinition;

    public this([NotNull] provider : CciMetadataProvider, [NotNull] paramDef : MsCci.IParameterDefinition)
    {
      _paramDef = paramDef;
      _provider = provider;
    }

    private _provider : CciMetadataProvider;

    public override ToString() : string
    {
      $"Parameter : $Name"
    }
  }
}
